home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagd_f.zip / EXEC.SWG / 0010_Trapping INT29 Output.pas < prev    next >
Pascal/Delphi Source File  |  1993-11-02  |  8KB  |  362 lines

  1. {
  2. TRISDARESA SUMARJOSO
  3.  
  4. > I was wondering if anyone knew how to make a split screen While
  5. > making EXEC calls and not losing your Windows?
  6.  
  7. > Anyone got any ideas or routines that do this? I can do it easily
  8. > using TTT when I just stay Within the Program, but the problems arise
  9. > when I do the SwapVectors and do my Exec call, all hell breaks loose.
  10. > Lynn.
  11.  
  12.         Here is a Unit that I've created to trap Int 29h. the Function of this
  13. Unit is to trap the output that Dos spits through the Int 29h (such as XCopy,
  14. PkZip, etc) and redirect it into a predefined Window.
  15.         Here is the stuff:
  16. }
  17.  
  18. Unit I29UnitA;
  19.  
  20. { This Unit will trap Dos output which use Int 29h. Any other
  21.   method of writing the scren, such as Direct Write which bypasses
  22.   Int 29h call, will not be trapped. }
  23.  
  24. Interface
  25.  
  26. { Initialize the view that will be use to output the Dos output.
  27.   Will also draw basic Window frame. }
  28. Procedure InitView(XX1, XY1, XX2, XY2 : Byte);
  29. { Clear the pre-defined view. }
  30. Procedure ClearView;
  31. { Procedure to redirect the Turbo Pascal Write and WriteLn Procedure.
  32.   (standard OutPut only).
  33.   Do not call this Procedure twice in the row.
  34.   More than once call to this Procedure will result Pascal's standard
  35.   output Procedure will not be restored properly. }
  36. Procedure TrapWrite;
  37. { Restore Pascal's Write and WriteLn Procedure into its original
  38.   condition that was altered With TRAPWrite. (standard OutPut only). }
  39. Procedure UnTrapWrite;
  40.  
  41. Implementation
  42.  
  43. Uses
  44.   Dos;
  45.  
  46. Type
  47.   VioCharType = Record
  48.     Case Boolean Of
  49.       True  : (Ch, Attr : Byte);
  50.       False : (Content : Word);
  51.     end;
  52.  
  53.   DrvFunc    = Function(Var F : TextRec) : Integer;
  54.   VioBufType = Array [0..24, 0..79] Of VioCharType;
  55.  
  56. Var
  57.   OldInt29     : Pointer;
  58.   OldExit      : Pointer;
  59.   OldIOFunc    : DrvFunc;
  60.   OldFlushFunc : DrvFunc;
  61.   TrapWriteVar : Boolean;
  62.   X1, Y1, X2,
  63.   Y2           : Byte;
  64.   XVio         : Byte;
  65.   YVio         : Byte;
  66.   VioBuffer    : ^VioBufType;
  67.   VioCurLoc    : Word Absolute $0040:$0050;
  68.  
  69. {$F+}
  70. Procedure NewInt29(Flags, CS, IP, AX, BX, CX, DX, SI, DI, DS, ES, BP: Word);
  71. Interrupt;
  72. begin
  73.   VioBuffer^[YVio, XVio].Attr := VioBuffer^[YVio, XVio].Attr And Not 112;
  74.   if (Lo(AX) = 13) Then
  75.   begin
  76.     XVio := X1;
  77.     AX := 0;
  78.   end
  79.   else
  80.   if (Lo(AX) = 10) Then
  81.   begin
  82.     Inc(YVio);
  83.     AX := 0;
  84.   end;
  85.   begin
  86.     if (XVio > X2) Then
  87.     begin
  88.       XVio := X1;
  89.       Inc(YVio);
  90.     end;
  91.     if (YVio > Y2) Then
  92.     begin
  93.       Asm
  94.         Mov   AH, 06
  95.         Mov   AL, YVio
  96.         Sub   AL, Y2
  97.         Mov   CH, Y1
  98.         Mov   CL, X1
  99.         Mov   DH, Y2
  100.         Mov   DL, X2
  101.         Mov   BH, 07
  102.         Int   10h
  103.       end;
  104.  
  105.       YVio := Y2;
  106.     end;
  107.  
  108.     if (Lo(AX) = 32) Then
  109.     begin
  110.       if (Lo(VioCurLoc) < XVio) Then
  111.       begin
  112.         XVio := Lo(VioCurLoc);
  113.         VioBuffer^[YVio, XVio].Ch := Lo(AX);
  114.       end
  115.       else
  116.       begin
  117.         VioBuffer^[YVio, XVio].Ch := Lo(AX);
  118.         Inc(XVio);
  119.       end;
  120.     end
  121.     else
  122.     begin
  123.       VioBuffer^[YVio, XVio].Ch := Lo(AX);
  124.       Inc(XVio);
  125.     end;
  126.     VioCurLoc := YVio Shl 8 + XVio;
  127.   end;
  128.   VioBuffer^[YVio, XVio].Attr := VioBuffer^[YVio, XVio].Attr Or 112;
  129. end;
  130. {$F-}
  131.  
  132. {$F+}
  133. Procedure RestoreInt29;
  134. begin
  135.   ExitProc := OldExit;
  136.   SetIntVec($29, OldInt29);
  137.   if TrapWriteVar Then
  138.   begin
  139.     TextRec(OutPut).InOutFunc := @OldIOFunc;
  140.     TextRec(OutPut).FlushFunc := @OldFlushFunc;
  141.   end;
  142. end;
  143. {$F-}
  144.  
  145. Procedure HookInt29;
  146. begin
  147.   GetIntVec($29, OldInt29);
  148.   SetIntVec($29, @NewInt29);
  149.   OldExit := ExitProc;
  150.   ExitProc := @RestoreInt29;
  151. end;
  152.  
  153. Procedure InitView(XX1, XY1, XX2, XY2: Byte);
  154. Var
  155.   I    : Byte;
  156. begin
  157.   X1 := XX1+1;
  158.   Y1 := XY1+1;
  159.   X2 := XX2-1;
  160.   Y2 := XY2-1;
  161.   XVio := X1;
  162.   YVio := Y1;
  163.   For I := XX1 To XX2 Do
  164.   begin
  165.     VioBuffer^[XY1, I].Ch := 205;
  166.     VioBuffer^[XY2, I].Ch := 205;
  167.   end;
  168.   For I := XY1+1 To XY2-1 Do
  169.   begin
  170.     VioBuffer^[I, XX1].Ch := 179;
  171.     VioBuffer^[I, XX2].Ch := 179;
  172.   end;
  173.   VioBuffer^[XY1, XX1].Ch := 213;
  174.   VioBuffer^[XY2, XX1].Ch := 212;
  175.   VioBuffer^[XY1, XX2].Ch := 184;
  176.   VioBuffer^[XY2, XX2].Ch := 190;
  177.   VioCurLoc := YVio Shl 8 + XVio;
  178. end;
  179.  
  180. Procedure DoWriteStuff(F : TextRec);
  181. Var
  182.   I    : Integer;
  183.   Regs : Registers;
  184. begin
  185.   For I := 0 To F.BufPos-1 Do
  186.   begin
  187.     Regs.AL := Byte(F.BufPtr^[I]);
  188.     Intr($29, Regs);
  189.   end;
  190. end;
  191.  
  192. {$F+}
  193. Function NewOutputFunc(Var F : TextRec) : Integer;
  194. begin
  195.   DoWriteStuff(F);
  196.   F.BufPos := 0;
  197.   NewOutPutFunc := 0;
  198. end;
  199. {$F-}
  200.  
  201. {$F+}
  202. Function NewFlushFunc(Var F : TextRec) : Integer;
  203. begin
  204.   DoWriteStuff(F);
  205.   F.BufPos := 0;
  206.   NewFlushFunc := 0;
  207. end;
  208. {$F-}
  209.  
  210. Procedure TrapWrite;
  211. begin
  212.   if Not TrapWriteVar Then
  213.   begin
  214.     With TextRec(OutPut) Do
  215.     begin
  216.       OldIOFunc := DrvFunc(InOutFunc);
  217.       InOutFunc := @NewOutPutFunc;
  218.       OldFlushFunc := DrvFUnc(FlushFunc);
  219.       FlushFunc := @NewFlushFunc;
  220.     end;
  221.     TrapWriteVar := True;
  222.   end;
  223. end;
  224.  
  225. Procedure UnTrapWrite;
  226. begin
  227.   if TrapWriteVar Then
  228.   begin
  229.     TextRec(OutPut).InOutFunc := @OldIOFunc;
  230.     TextRec(OutPut).FlushFunc := @OldFlushFunc;
  231.     TrapWriteVar := False;
  232.   end;
  233. end;
  234.  
  235. Procedure ClearView;
  236. begin
  237.   Asm
  238.     Mov   AH, 06
  239.     Mov   AL, 0
  240.     Mov   CH, Y1
  241.     Mov   CL, X1
  242.     Mov   DH, Y2
  243.     Mov   DL, X2
  244.     Mov   BH, 07
  245.     Int   10h
  246.   end;
  247.   XVio := X1;
  248.   YVio := Y1;
  249.   VioCurLoc := YVio Shl 8 + XVio;
  250. end;
  251.  
  252. Procedure CheckMode;
  253. Var
  254.   MyRegs : Registers;
  255. begin
  256.   MyRegs.AH := $F;
  257.   Intr($10, MyRegs);
  258.   Case MyRegs.AL Of
  259.     0, 1, 2, 3  : VioBuffer := Ptr($B800, $0000);
  260.     7           : VioBuffer := Ptr($B000, $0000);
  261.   end;
  262. end;
  263.  
  264. begin
  265.   X1 := 0;
  266.   Y1 := 0;
  267.   X2 := 79;
  268.   Y2 := 24;
  269.   XVio := 0;
  270.   YVio := 0;
  271.   VioCurLoc := YVio Shl 8 + XVio;
  272.   HookInt29;
  273.   TrapWriteVar := False;
  274.   CheckMode;
  275. end.
  276.  
  277.  
  278. Program Int29Testing;
  279.  
  280. {$A+,B-,D+,E+,F-,G-,I+,L+,N-,O-,P-,Q-,R-,S+,T-,V+,X+}
  281. {$M $800,0,0}
  282.  
  283. Uses
  284.   Dos, Crt,
  285.   I29UnitA;
  286.  
  287. Var
  288.   CmdLine      : String;
  289.   I            : Byte;
  290.  
  291. { Function to convert a String to upper case.
  292.   Return the upper-case String. }
  293.  
  294. Function Str2Upr(Str : String) : String; Assembler;
  295. Asm
  296.   Push DS
  297.   CLD
  298.   LDS  SI, Str
  299.   LES  DI, @Result
  300.   LodSB
  301.   Or   AL, AL
  302.   Jz   @Done
  303.   StoSB
  304.   Xor  CH, CH
  305.   Mov  CL, AL
  306.  @@1:
  307.   LodSB
  308.   Cmp  AL, 'a'
  309.   JB   @@2
  310.   Cmp  AL, 'z'
  311.   JA   @@2
  312.   Sub  AL, 20h
  313.  @@2:
  314.   StoSB
  315.   Loop @@1
  316.  @Done:
  317.   Pop  DS
  318. end;
  319.  
  320. begin
  321.   ClrScr;
  322.   GotoXY(1,1);
  323.   WriteLn('Output interceptor.');
  324.   { Initialize redirector's area. }
  325.   InitView(0,2,79,24);
  326.   Repeat
  327.           { Redirect Turbo's output into the predefined Window. }
  328.     TrapWrite;
  329.     Write(#0,' Please enter Dos command (Done to Exit): ');
  330.     ReadLn(CmdLine);
  331.     WriteLn;
  332.     { Restore Turbo's original Output routine. }
  333.     UnTrapWrite;
  334.     GotoXY(1,2);
  335.     WriteLn('Command executed : ', CmdLine);
  336.     CmdLine := Str2Upr(CmdLine);
  337.     if (CmdLine <> 'DONE') And (CmdLine <> '') Then
  338.     begin
  339.       SwapVectors;
  340.       Exec('C:\Command.Com', '/C'+CmdLine);
  341.       SwapVectors;
  342.     end;
  343.     GotoXY(1,2);
  344.     WriteLn('Command execution done. Press anykey to continue...');
  345.     Repeat Until ReadKey <> #0;
  346.     ClearView;
  347.     GotoXY(1,2);
  348.     WriteLn('                                                   ');
  349.   Until (CmdLine = 'DONE');
  350.   ClrScr;
  351. end.
  352.  
  353. {
  354. Both the testing Program and the Unit itself (expecially the Unit), is by no
  355. mean perfect. Use With caution. It might not wise to use such redirector
  356. (my int 29 Unit) in a Program that swaps itself out of memory. The above
  357. Programs were not optimized in anyway (so it might slow your Program a
  358. little). And I don't guarantee that this Program will work on your computer
  359. (it work Without a problem on mine). if you like this Unit, you can use it
  360. anyway you desire. Just remember I can guarantee nothing For this method.
  361. }
  362.